/*Simple Caesar Cipher - This program works with standard ascii text files.
It will find the most common letter, assume that this letter is e, and
shift the text to form a decryted message
Program by Brian Gorman*/

#include <iostream>
#include <fstream>
#include <cctype>
#include <string>

using namespace std;

void initialize(int list[]);
void characterCount(char ch, int list[]);
void calcShift(int& shift, int list[]);
void writeOutput(ifstream &in, ofstream &out, int shift);

int main()
{
    int letterCount[26];
    char ch = 0;
	int shift = 0;
    ifstream inFile; 
    ofstream outFile;
	string inputFileName;
	string output;
	cout<<"Welcome to Simple Caesar Cipher\n"
		<<"Please enter the input file's full location\n";
	getline(cin, inputFileName);
	cout<<"Please enter the output file's full location\n";
	getline(cin, output);
    inFile.open(inputFileName.c_str());
	outFile.open(output.c_str()); 
    if (!inFile)   // check for successful opening                                  
    {
        cout << "Cannot open the input file." 
             << endl;
		exit(0);
        
    }
    initialize(letterCount); //zero array            
    inFile.get(ch);       
    while (inFile)    //fill array with number of letter occurances                          
    {
        while (ch != '\n' && ch != ' ')      
		{
			characterCount(ch, letterCount);                   
			inFile.get(ch);     
		}                               
        inFile.get(ch);                            
    }
	calcShift(shift, letterCount); // calculate shift
	writeOutput(inFile, outFile, shift); // output file....
	outFile.close();
	inFile.close();
    return 0;
}

//function to "zero" array"
void initialize(int list[])
{
    for (int j = 0; j < 26; j++)
        list[j] = 0;
}
//Function to count the number of time a character occurs in text
void characterCount(char ch, int list[])
{
    int index;
    ch = toupper(ch);                       
    index = int (ch) - int ('A');       
    if (0 <= index && index < 26)           
        list[index]++;
}
//function to calculate most frequent character and the shift away from 'e'
void calcShift(int& shift, int list[])
{
	int highest = 0;
	for (int count = 0; count < 26; count++)
	{
		if (list[count] > list[highest])
			highest = count;
	}
	if(highest > 4)
		shift = highest - 4; //subtract ascii e value
	else
		shift = 4 - highest; //subtract from ascii e value

}
//function to output text file 
void writeOutput(ifstream &in, ofstream &out, int shift) 
{
	in.clear();
	in.seekg(0);
	char c = 0;
	int temp,numVal, back;
	while (!in.eof())
	{
		in.get(c);
		numVal=int(c);
		if(numVal >= 65 && numVal <= 90) //if between UPPER 26 letter
		{
			temp = (c - 65 - shift); 
			back = 65; //ASCII 'A' / value to return char to once done shifting
		}

		else if (numVal >= 97 && numVal <= 122) //if between lower 26 letter
		{
			temp = (c - 97 - shift);
            back = 97; //ASCII 'a' / value to return char to once done shifting
		}
		else
		{
			out<<c;
			continue;
		}
		if (temp < 0)
		{
			out<<char(temp + 26 + back);
		}
        else
		{
            out<<char(temp + back);
		}
	}
}
